﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls;
using Silvermoon.Images;
using ShoppingList.Biz;
using ShoppingList.DTO;
using Silvermoon.Controls.Forms;
using Silvermoon.UI;
using ShoppingList.Pages;
using Silvermoon.Navigation;
using Silvermoon.Windows;

namespace ShoppingList
{
    public class ShoppingListPage : Page
    {

        private TabControl tabs;
        private TabPage completedPage, schedulePage, activePage, allPage;
        private ListView todoView, completedView, scheduleView, allView;
        private ListViewController<CheckItem, ShoppingItem> completedController, todoController, scheduleController, allController;
        private ContextMenu contextMenu;

        public ShoppingListPage()
            : base()
        {
            InitializePage();
        }

        public BizContext Context { get { return BizContext.Context; } }

        protected override void Dispose(bool dispose)
        {
            DisposeObject(contextMenu);
            base.Dispose(dispose);
        }

        private void InitializePage()
        {
            Styles = StylePool.Main;
            Title = "SHOPPING LIST";
            SetTransition(350, TransitionMask.RotateLeftOut, TransitionMask.RotateLeftOut);

            tabs = new TabControl { Margin = Margin.Zero };

            todoView = new ListView { Margin = Margin.Zero, Multiselect = true };
            completedView = new ListView { Margin = Margin.Zero, Multiselect = true };
            scheduleView = new ListView { Margin = Margin.Zero, Multiselect = true };
            allView = new ListView { Margin = Margin.Zero, Multiselect = true };

            activePage = new TabPage("todo", todoView);
            completedPage = new TabPage("done", completedView);
            allPage = new TabPage("all", allView);
            schedulePage = new TabPage("scheduled", scheduleView);
            tabs.SetPages(activePage, allPage, completedPage, schedulePage);
            Controls.Add(tabs);

            contextMenu = new ContextMenu();
            contextMenu.AddItem("Schedule").Tap += new EventHandler<TapEventArgs>(OnSchedule);

            Toolbar tb = new Toolbar();
            tb.AddButton(SysImages.Add).Tap += new EventHandler<TapEventArgs>(OnNewList);
            tb.AddButton(SysImages.Edit).Tap += new EventHandler<TapEventArgs>(OnEditList);
            tb.AddMenuItem("edit list").Tap += new EventHandler<TapEventArgs>(OnEditList);
            tb.AddMenuItem("new list").Tap += new EventHandler<TapEventArgs>(OnNewList);
            tb.AddMenuItem("complete shopping tour").Tap += new EventHandler<TapEventArgs>(OnCompleteShoppingTour);
            Toolbar = tb;

            CreateControllers();
        }

        void OnNewList(object sender, TapEventArgs e)
        {
            Context.ClearEditListItems();
            if (Context.ActiveItems.Count > 0)
            {
                MessageDialog.Show("CREATE NEW LIST?", "The current shopping list will be overridden if the changes in the list editor are accepted.", "yes", "no", OpenNewListPage, null);
            }
            else OpenNewListPage();
        }

        private void OpenNewListPage()
        {
            EditListPage page = new EditListPage();
            this.NavigateTo(page);
        }

        void OnEditList(object sender, TapEventArgs e)
        {
            Context.UpdateEditListtems();
            EditListPage page = new EditListPage();
            this.NavigateTo(page);
        }

        void OnCompleteShoppingTour(object sender, TapEventArgs e)
        {
            MessageDialog.Show("Complete shopping?", "Items marked as completed will be deleted and scheduled items will become active.", "Complete", "Cancel", CompleteShoppingTour, null);
        }

        private void CompleteShoppingTour()
        {
            BizContext.Open();
            Context.FinishShoppingTour();
            UpdateData();
        }

        void OnSchedule(object sender, TapEventArgs e)
        {
            CheckItem item = contextMenu.AnchorControl as CheckItem;
            var si = item != null ? item.ShoppingItem : null;
            if (si != null)
            {
                si.IsScheduled = true;
                allController.RemoveValue(si);
                Sync();
            }
        }

        private void CreateControllers()
        {
            BizContext.Open();
            todoController = CreateController(todoView);
            scheduleController = CreateController(scheduleView);
            completedController = CreateController(completedView);
            allController = CreateController(allView);


            todoController.UpdateItem += new EventHandler<ItemControlGeneratorEventArgs<CheckItem>>(activeController_UpdateItem);
            allController.UpdateItem += activeController_UpdateItem;
            scheduleController.UpdateItem += new EventHandler<ItemControlGeneratorEventArgs<CheckItem>>(scheduleController_UpdateItem);
            completedController.InitializeItem += new EventHandler<ItemControlGeneratorEventArgs<CheckItem>>(completedController_InitializeItem);

            UpdateData();
        }

        void completedController_InitializeItem(object sender, ItemControlGeneratorEventArgs<CheckItem> e)
        {
            //e.Item.TextColor = PhoneColors.Lime;
            e.Item.Opacity = 160;
        }

        void scheduleController_UpdateItem(object sender, ItemControlGeneratorEventArgs<CheckItem> e)
        {
            e.Item.Enabled = false;
        }

        void activeController_UpdateItem(object sender, ItemControlGeneratorEventArgs<CheckItem> e)
        {
            contextMenu.UndoAnchor(false);
            e.Item.ContextMenu = contextMenu;
        }

        private ListViewController<CheckItem, ShoppingItem> CreateController(ListView view)
        {
            var controller = new ListViewController<CheckItem, ShoppingItem>(view) { ItemHeight = 81, ValueComparer = CompareShoppingItems };
            controller.InitializeItem += new EventHandler<ItemControlGeneratorEventArgs<CheckItem>>(OnInitializeItem);
            return controller;
        }

        void OnInitializeItem(object sender, ItemControlGeneratorEventArgs<CheckItem> e)
        {
            e.Item.Tap += new EventHandler<TapEventArgs>(OnTapItem);
        }

        void OnTapItem(object sender, TapEventArgs e)
        {
            Sync();
        }

        public static int CompareShoppingItems(ShoppingItem a, ShoppingItem b)
        {
            return string.Compare(a.Name, b.Name, true);
        }

        private void UpdateData()
        {
            var context = Context;
            context.Update();
            todoController.DataSource = context.ActiveItems;
            scheduleController.DataSource = context.ScheduledItems;
            completedController.DataSource = context.CompletedItems;
            allController.DataSource = context.Items.Where(i => i.IsScheduled == false);
        }

        void Sync()
        {
            var context = Context;
            if (tabs.SelectedPage == activePage)
            {
                var itemsToRemove = context.ActiveItems.Where(i => i.IsCompleted == true || i.IsScheduled == true).ToArray();
                foreach (var item in itemsToRemove)
                {
                    todoController.RemoveValue(item);
                }
                context.Update();
                scheduleController.DataSource = context.ScheduledItems;
                completedController.DataSource = context.CompletedItems;
            }
            else if (tabs.SelectedPage == completedPage)
            {
                var itemsToRemove = context.CompletedItems.Where(i => i.IsCompleted == false).ToArray();
                foreach (var item in itemsToRemove)
                {
                    completedController.RemoveValue(item);
                }
                context.Update();
                todoController.DataSource = context.ActiveItems;
                scheduleController.DataSource = context.ScheduledItems;
            }
            else
            {
                context.Update();
                completedController.DataSource = context.CompletedItems;
                todoController.DataSource = context.ActiveItems;
                scheduleController.DataSource = context.ScheduledItems;
            }
        }

        protected override void OnShown()
        {
            base.OnShown();
            Keyboard.Enabled = true;
        }
    }
}
